17 AGT 周期测量实验

开发板官网(https://www.edevkit.com/)
本系列教程目录:
- 瑞萨单片机开发教程[一] e2-studio + DAP LINK开发环境搭建
- 瑞萨单片机开发教程[二] Keil/RASC开发环境搭建
- 瑞萨单片机开发教程[三] 新建RASC工程
- 瑞萨单片机开发教程[四] GPIO输出——led实验
- 瑞萨单片机开发教程[五] GPIO输入——按键key实验
- 瑞萨单片机开发教程[六] ICU外部中断实验
- 瑞萨单片机开发教程[七] SCI UART串口通信实验
- 瑞萨单片机开发教程[八] DMAC 串口数据传输实验
- 瑞萨单片机开发教程[九] ADC 电压采集实验
AGT 脉冲周期测量实验
本章目标:
- 了解 RA6M5 处理器的 AGT 外设;
- 学会使用 RASC 配置 AGT 脉冲周期测量功能;
硬件设计
(略,参见配套硬件原理图)
软件设计
新建工程
复制一份“15 AGT_PWM_Output”修改文件夹名“17 AGT_Pulse_Period”,双击打开 EBF_RA6M5.uvprojx 工程,通过 Keil 的新建文件新建 agt_pulse_period.c 和 agt_pulse_period.h,保存到目录下的 src 文件夹下。
FSP 配置
Keil 界面选择“Tools”→“RA Smart Configurator”打开 RASC 界面。
周期测量需要配置输入引脚 P600,需要先在“Pins”配置页中为 AGT3 配置引脚,将 AGT3 的 AGTIO3 信号输出设置为 P600 引脚。

添加 AGT Stack 模块。

属性配置:

“Input”属性:
“Measurement Mode”:测量模式。
选择 AGT 是否用于测量脉冲宽度或脉冲周期。默认禁止测量,可选择测量低电平脉冲宽度、高电平脉冲宽度和脉冲周期。
“Input Filter”:输入滤波器。
该滤波器要求从 AGTIO 引脚输入信号在指定的滤波器频率下连续 3 次读取时处于同一电平。
“Enable Pin”:使能引脚。
选择 AGTEE 引脚的有效边缘。仅当 P402、P403 或者 AGTIO 作为时钟源的时候可用。
“Trigger Edge”:选择触发边缘。
不要同时选择触发边缘与脉冲周期。
配置完成之后可以按下快捷键“Ctrl + S”保存,最后点击“Generate Project Content”按钮,让软件自动生成配置代码即可。
程序设计
实现 AGT 的输入脉冲周期测量功能,开启 AGT3 通道的周期测量,设置 AGT0 输出的 PWM 占空比,连接 P500 和 P600,测量输入的 PWM 的脉冲周期,并打印到串口。
- 打开 AGT 设备
R_AGT_Open(timer_ctrl_t * const p_ctrl, timer_cfg_t const * const p_cfg);
p_ctrl:timer_ctrl_t 结构体指针参数,本质是一个 void 类型的参数,指向 st_gpt_instance_ctrl 类型变量;
p_cfg:timer_cfg_t 结构体指针参数,在程序中会指向在 hal_data.c 中定义的 g_timer_cfg 静态全局变量;
- 开启/停止 AGT 计数
R_AGT_Start(timer_ctrl_t * const p_ctrl);
R_AGT_Stop(timer_ctrl_t * const p_ctrl);
必须要在 AGT 打开状态下使用这两个函数。
- 脉宽测量完成中断
void agt3_pulse_period_measurement_callback(timer_callback_args_t * p_args)
{
//测量完成事件
if (TIMER_EVENT_CAPTURE_A == p_args->event)
{
}
//定时器计数溢出事件
else if (TIMER_EVENT_CYCLE_END == p_args->event)
{
}
}
程序编写
在 agt_pulse_period.h 头文件里定义初始化函数、打印数据函数。
#ifndef __BSP_AGT_PULSE_PERIOD_H
#define __BSP_AGT_PULSE_PERIOD_H
#include "hal_data.h"
void agt_Pulse_Period_Init(void);
void scan_over_printf(void);
#endif
在 agt_pulse_period.c 里实现初始化函数、中断函数。
#include "agt_pulse_period.h"
timer_info_t agtInfo;
uint32_t periodCnts; //计数周期值
//初始化函数
void agt_Pulse_Period_Init(void)
{
//打开 AGT 模块
R_AGT_Open(&g_timer_agt3_ctrl, &g_timer_agt3_cfg);
// 获取计数周期
R_AGT_InfoGet(&g_timer_agt3_ctrl, &agtInfo);
periodCnts = agtInfo.period_counts;
//使能 AGT 定时器
R_AGT_Start(&g_timer_agt3_ctrl);
}
uint32_t pulse_height_time; //高电平宽度时间
uint8_t over_flag; //测量完成标志
uint32_t overflow_times = 0; //计数器溢出次数
//脉冲宽度测量中断函数
void agt3_pulse_period_callback(timer_callback_args_t * p_args)
{
//测量完成标志
if (TIMER_EVENT_CAPTURE_A == p_args->event)
{
//记录时间 B
pulse_height_time = p_args->capture + overflow_times * periodCnts;
overflow_times = 0;
over_flag = 1; //测量完成
}
//定时器计数溢出
else if (TIMER_EVENT_CYCLE_END == p_args->event)
{
//输入捕获期间计数器溢出,则记录溢出次数+1
overflow_times++;
}
}
//打印测量数据
void scan_over_printf(void)
{
float time_us = 0;
if(over_flag)
{
//打印PWM周期的计数
printf("High=%d, ", pulse_height_time);
//计算PWM的周期
time_us = (float)pulse_height_time / ((float)agtInfo.clock_frequency / (float)1000000);
printf("High Time=%f us\r\n", time_us);
overflow_times = 0;
over_flag = 0;
}
}
在 hal_entry.c 文件中添加头文件 agt_pulse_period.h,在 hal_entry 入口函数初始化 AGT。
void hal_entry(void)
{
/* TODO: add your own code here */
led_Init();
uart0_Init();
agt_PWM_Init();
agt_Pulse_Period_Init();
printf("start AGT Pulse Period test\r\n");
while(1)
{
LED1_TOGGLE();
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
scan_over_printf();
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
下载验证
连接下载器,将程序编译并下载到开发板之后,按下复位按键来复位开发板,程序启动初始化完成后,观察实验结果。
设置 AGT0 的 PWM 输出频率为 20 kHz,观察到测量数据,周期时间为 50 μs。
